
# XML（eXtensible Markup Language）解析
'''
python有三种方法解析XML，SAX、DOM 以及 ElementTree。
常见的XML编程接口有DOM和SAX，这两种接口处理XML文件的方式不同，使用场合也不同。
SAX (Simple API for XML)
SAX用事件驱动模型，在解析XML的过程中触发事件并调用用户定义的回调函数来处理XML文件。
DOM (Document Object Model)
将XML数据在内存中解析成一个树，通过对树的操作来操作XML。
'''

# 使用 xml.sax 解析 xml
'''
SAX是一种基于事件驱动的API。
利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器。
解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;
而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。
适用于：
1、对大型文件进行处理；
2、只需要文件的部分内容，或者只需从文件中得到特定信息。
3、想建立自己的对象模型的时候。
'''
'''
xml.sax.ContentHandler类方法介绍
characters(content)方法
调用时机：
从行开始，遇到标签之前，存在字符，content的值为这些字符串。
从一个标签，遇到下一个标签之前， 存在字符，content的值为这些字符串。
从一个标签，遇到行结束符之前，存在字符，content的值为这些字符串。
标签可以是开始标签，也可以是结束标签。
startDocument()             文档启动的时候调用。
endDocument()               解析器到达文档结尾时调用。
startElement(name, attrs)   遇到XML开始标签时调用，name是标签的名字，attrs是标签的属性值字典。
endElement(name)            遇到XML结束标签时调用。
'''
'''
xml.sax.make_parser( [parser_list] )
创建一个新的解析器对象并返回。
parser_list - 可选参数，解析器列表

xml.sax.parse( xmlfile, contenthandler[, errorhandler])
创建一个 SAX 解析器并解析xml文档
xmlfile - xml文件名
contenthandler - 必须是一个ContentHandler的对象
errorhandler - 如果指定该参数，errorhandler必须是一个SAX ErrorHandler对象

xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
创建一个XML解析器并解析xml字符串.
xmlstring - xml字符串
contenthandler - 必须是一个ContentHandler的对象
errorhandler - 如果指定该参数，errorhandler必须是一个SAX ErrorHandler对象
'''
'''
import xml.sax
class MovieHandler( xml.sax.ContentHandler ):
    # 初始化xml标签名字和属性值
    def __init__(self):
        self.CurrentData = ""
        self.type = ""
        self.format = ""
        self.year = ""
        self.rating = ""
        self.stars = ""
        self.description = ""
    # 开始解析文件
    def startDocument(self):
        print('-'*10, "start", '-'*10)

    # 到达文档结尾
    def endDocument(self):
        print('-'*10, "end", '-'*10)

    # 元素开始调用
    def startElement(self, tag, attributes):
        self.CurrentData = tag
        if tag == "movie":
            print ("\n[Movie]")
            title = attributes["title"]
            print ("Title:", title)

    # 元素结束调用
    def endElement(self, tag):
        if self.CurrentData == "type":
            print ("Type:", self.type)
        elif self.CurrentData == "format":
            print ("Format:", self.format)
        elif self.CurrentData == "year":
            print ("Year:", self.year)
        elif self.CurrentData == "rating":
            print ("Rating:", self.rating)
        elif self.CurrentData == "stars":
            print ("Stars:", self.stars)
        elif self.CurrentData == "description":
            print ("Description:", self.description)
        self.CurrentData = ""

    # 读取字符时调用
    def characters(self, content):
        if self.CurrentData == "type":
            self.type = content
        elif self.CurrentData == "format":
            self.format = content
        elif self.CurrentData == "year":
            self.year = content
        elif self.CurrentData == "rating":
            self.rating = content
        elif self.CurrentData == "stars":
            self.stars = content
        elif self.CurrentData == "description":
            self.description = content

if ( __name__ == "__main__"):
    # 创建一个 XMLReader
    parser = xml.sax.make_parser()
    # turn off namespaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重写 ContextHandler
    Handler = MovieHandler()
    parser.setContentHandler( Handler )
    parser.parse("movies.xml")
'''

# 使用 xml.dom 解析 xml
'''
DOM 的解析器在解析 XML 文档时，一次性读取整个文档，把文档中所有元素保存在内存中的一个树结构里.
利用DOM 提供的不同的函数来读取或修改文档的内容和结构，也可以把修改过的内容写入xml文件。
'''
import xml.dom.minidom
# 使用minidom解析器打开 XML 文档
domTree = xml.dom.minidom.parse("movies.xml")
collection = domTree.documentElement
if collection.hasAttribute("shelf"):
   print ("Root element : %s" % collection.getAttribute("shelf"))

# 在集合中获取所有电影
movies = collection.getElementsByTagName("movie")

# 打印每部电影的详细信息
for movie in movies:
   print ("*****Movie*****")
   if movie.hasAttribute("title"):
      print ("Title: %s" % movie.getAttribute("title"))
   type = movie.getElementsByTagName('type')[0]
   print ("Type: %s" % type.childNodes[0].data)
   format = movie.getElementsByTagName('format')[0]
   print ("Format: %s" % format.childNodes[0].data)
   rating = movie.getElementsByTagName('rating')[0]
   print ("Rating: %s" % rating.childNodes[0].data)
   description = movie.getElementsByTagName('description')[0]
   print ("Description: %s" % description.childNodes[0].data)
